package org.yangspring.samples.mvc.daoOracle;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ApplicationEvent;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.support.TransactionSynchronizationManager;
import org.springframework.web.context.ServletContextAware;
import org.springframework.web.context.WebApplicationContext;
import org.yangspring.samples.mvc.domainOracle.DBAViews;
import org.yangspring.samples.mvc.listeners.ContentEvent;

import javax.servlet.ServletContext;
import java.util.Enumeration;
import java.util.List;

import static java.lang.System.out;

/**
 * Created by franklin on 6/24/2017.
 */

@Repository
public class DBAViewsDAOImpl implements DBAViewsDAO, ServletContextAware, ApplicationContextAware {
    private static final Logger logger = LoggerFactory.getLogger(DBAViewsDAO.class);

    private ServletContext svltCntxAwr;
    private ApplicationContext appCntxAwr;

    @Autowired
    private ServletContext svltCntx;
    @Autowired
    private ApplicationContext appCntx;


    public void setServletContext(ServletContext svltCntxAwr)
            throws BeansException {
        this.svltCntxAwr = svltCntxAwr;
    }

    public void setApplicationContext(ApplicationContext appCntxAwr)
            throws BeansException {
        this.appCntxAwr = appCntxAwr;
    }


    /*public void setSessionFactory(SessionFactory sessionFactory){
        this.sessionFactory = sessionFactory;
    }*/


    @Autowired
    @Qualifier("hibernate5AnnotatedSessionFactoryOracle")
    private SessionFactory sessionFactory;

    /****
     * Way 2 for use Autowired Annotation
     * **/
    /*@Autowired
    public void setApplicationContext(ApplicationContext appCntx){
        this.appCntx = appCntx;
    }*/

    public List<DBAViews> listDbaViews(){
//        Session session = this.sessionFactory.getCurrentSession();
        Session session = this.sessionFactory.openSession();
        TransactionSynchronizationManager.bindResource(this.sessionFactory, session);

        logger.warn("\nDBAViewsDAOImpl\n");

        /*TEXT, CONTAINER_DATA*/
        List<DBAViews> dbaViewsList = session.createSQLQuery("select VIEW_NAME, OWNER, TYPE_TEXT, OID_TEXT, " +
                "VIEW_TYPE " +
                "from DBA_VIEWS").addEntity(DBAViews.class).list();

        if (dbaViewsList.size() < 1){
            logger.warn("\n\ndbaViewsList has nothing !\n");
        }

        for(DBAViews t : dbaViewsList){
            logger.info("dbaViews List::" + t);
        }
        return dbaViewsList;
    }

    /*public List<DBAViews> listDbaViews4Owner(String owner){

        Session session = this.sessionFactory.getCurrentSession();
        logger.warn("\nDBAViewsDAOImpl for Owner\n");
        *//*TEXT, *//*
        List<DBAViews> dbaViewsList = session.createSQLQuery("select VIEW_NAME, OWNER, TYPE_TEXT, OID_TEXT," +
                "VIEW_TYPE, CONTAINER_DATA " +
                "from DBA_VIEWS " +
                "where owner = '" + owner.toUpperCase() + "'").addEntity(DBAViews.class).list();

        return dbaViewsList;
    }*/

    public List<DBAViews> listDbaViews4Name(String name){
//        Session session = this.sessionFactory.getCurrentSession();
        Session session = this.sessionFactory.openSession();
        TransactionSynchronizationManager.bindResource(this.sessionFactory, session);

        logger.warn("\nDBAViewsDAOImpl for Owner\n");
        /*TEXT, */
        List<DBAViews> dbaViewsList = session.createSQLQuery("select VIEW_NAME, OWNER, TYPE_TEXT, OID_TEXT," +
                "VIEW_TYPE " +
                "from DBA_VIEWS " +
                "where view_name like '%" + name.toUpperCase() + "%'").addEntity(DBAViews.class).list();

        return dbaViewsList;
    }

    public List<DBAViews> listDbaViews4NameOwner(String name, String owner){
//        Session session = this.sessionFactory.getCurrentSession();
        Session session = this.sessionFactory.openSession();
        TransactionSynchronizationManager.bindResource(this.sessionFactory, session);


        logger.warn(
                "WebApplicationContext 's member STRING:\t"
                + WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE
                + "\t\t"
                + WebApplicationContext.SERVLET_CONTEXT_BEAN_NAME
        );

        logger.warn(
                "\n\n\tAware ServletContext:\nRoot AC?\t"
                + this.svltCntxAwr.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE)
                + "\nSERVLET_CONTEXT_BEAN_NAME ???\t"
                + this.svltCntx.getAttribute(WebApplicationContext.SERVLET_CONTEXT_BEAN_NAME)
                + "\ngetServletContextName\t"
                + this.svltCntxAwr.getServletContextName()
                + "\ngetServerInfo\t"
                + this.svltCntxAwr.getServerInfo()
        );
        Enumeration<String> es = this.svltCntxAwr.getAttributeNames();
        while (es.hasMoreElements()){
            String _str = es.nextElement().toString();
            if (!_str.contains("jsp_classpath")){
                logger.warn("\tAware ServletContext3\t:" + _str + "\t\t" + this.svltCntxAwr.getAttribute(_str));
            }
        }

        logger.warn(
                "\n\n\tAutowired ServletContext:\nRoot AC?\t"
                + this.svltCntx.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE)
                + "\nSERVLET_CONTEXT_BEAN_NAME ???\t"
                + this.svltCntx.getAttribute(WebApplicationContext.SERVLET_CONTEXT_BEAN_NAME)
                + "\ngetServletContextName\t"
                + this.svltCntx.getServletContextName()
                + "\ngetServerInfo\t"
                + this.svltCntx.getServerInfo()
        );
        es = this.svltCntx.getAttributeNames();
        while (es.hasMoreElements()){
            String _str = es.nextElement().toString();
            if (!_str.contains("jsp_classpath")) {
                logger.warn("\tAware ServletContext3\t:" + _str + "\t\t" + this.svltCntx.getAttribute(_str));
            }
        }

        logger.warn(
                "\n\n\tAware ApplicationContext:\n1\t"
                + this.appCntxAwr.getApplicationName()
                + "\n2\t"
                + this.appCntxAwr.getParent()
                + "\n3a ROOT AC ?\t"
                + this.appCntxAwr.getParent().getDisplayName()
                + "\n3a ROOT AC 2?\t"
                + this.appCntxAwr.getParent().getApplicationName()
                + "\n3b MVC AC?\t"
                + this.appCntxAwr.getDisplayName()
                + "\n4 Quantity of Bean ?\t"
                + this.appCntxAwr.getBeanDefinitionCount()
        );

        logger.warn(
                "\n\n\t@Autowired ApplicationContext:\n1\t"
                + this.appCntxAwr.getApplicationName()
                + "\n2\t"
                + this.appCntx.getParent()
                + "\n3a ROOT AC ?\t"
                + this.appCntx.getParent().getDisplayName()
                + "\n3a ROOT AC 2?\t"
                + this.appCntx.getParent().getApplicationName()
                + "\n3b MVC AC?\t"
                + this.appCntx.getDisplayName()
                + "\n4 Quantity of Bean ?\t"
                + this.appCntx.getBeanDefinitionCount()
        );


        logger.warn("\nDBAViewsDAOImpl for Name and Owner\n");
        this.appCntx.publishEvent(new ContentEvent("Now FrankieYang 's Blog Updating from DBAViewsDAOImpl\n"));
        this.appCntx.publishEvent(new ApplicationEvent("Now WHYANG 's Blog Updating from DBAViewsDAOImpl\n") {
            @Override
            public Object getSource() {
                return super.getSource();
            }
        });

        /*TEXT, */
        List<DBAViews> dbaViewsList = session.createSQLQuery("select VIEW_NAME, OWNER, TYPE_TEXT, OID_TEXT, " +
                "VIEW_TYPE " +
                "from DBA_VIEWS " +
                "where " + ((name == "") ? "" : ("view_name like '%" + name.toUpperCase() + "%' and")) + " owner = '" + owner.toUpperCase() + "'").addEntity(DBAViews.class).list();

        return dbaViewsList;
    }

}
